package com.iplant.wms.serviceImpl.dao.mss;

import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.cache.CacheUtils;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.BaseDAO;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.basic.service.po.mss.MSSMaterial;
import com.iplant.basic.serviceImpl.dao.mss.MSSMaterialDAO;
import com.iplant.wms.service.po.mss.MSSTransferRange;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class MSSTransferRangeDAO extends BaseDAO {

    private static MSSTransferRangeDAO Instance = null;
    private static Logger logger = LoggerFactory.getLogger(MSSTransferRangeDAO.class);

    private MSSTransferRangeDAO() {
        super();

        setTableName("mss_transferrange");
    }

    public static MSSTransferRangeDAO getInstance() {
        if (Instance == null)
            Instance = new MSSTransferRangeDAO();
        return Instance;
    }

    public void MSS_UpdateTransferRange(BMSEmployee wLoginUser, MSSTransferRange wTransferRange, OutResult<Integer> wErrorCode) {
        wErrorCode.set(0);

        try {
            if (wTransferRange == null || StringUtils.isEmpty(wTransferRange.Name)) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return;
            }
            MSSTransferRange wTransferRangeO = this.MSS_CheckTransferRange(wLoginUser, wTransferRange, wErrorCode);
            if (wTransferRangeO.ID > 0) {
                if (wTransferRange.ID <= 0) {
                    wTransferRange.ID = wTransferRangeO.ID;
                } else {
                    wErrorCode.set(ExceptionTypes.Duplication.getValue());
                    return;
                }
            }
            if (wTransferRange.RuleID <= 0) {
                this.DeletePO(wLoginUser, wTransferRange, wErrorCode);
                return;
            }

            Map<String, Object> wParwms = new HashMap<String, Object>();

            /**
             * 非必填字段 可有可无
             */
            wParwms.put("Name", wTransferRange.Name);
            /**
             * 非必填字段 可有可无
             */
            wParwms.put("Code", wTransferRange.Code);


            wParwms.put("Description", wTransferRange.Description);
            wParwms.put("CustomerID", wTransferRange.CustomerID);
            wParwms.put("MaterialID", wTransferRange.MaterialID);
            wParwms.put("MaterialGroupID", wTransferRange.MaterialGroupID);
            wParwms.put("RuleID", wTransferRange.RuleID);

            wParwms.put("EditorID", wLoginUser.getID());
            wParwms.put("EditTime", Calendar.getInstance());


            if (wTransferRange.ID > 0) {
                wParwms.put("ID", wTransferRange.ID);
                super.Update(super.getTableName("mss_transferrange"), "ID", wParwms);
            } else {
                wParwms.put("CreatorID", wLoginUser.getID());
                wParwms.put("CreateTime", Calendar.getInstance());
                wParwms.put("Active", 1);
                wTransferRange.ID = super.Insert(super.getTableName("mss_transferrange"), wParwms);

            }

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("MSS_UpdateTransferRange", ex);
        }
    }


    public void MSS_DeleteTransferRange(BMSEmployee wLoginUser, int wRuleID, OutResult<Integer> wErrorCode) {
        wErrorCode.set(0);

        try {
            if (wRuleID <= 0) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return;
            }
            Map<String, Object> wDeleteParwms = new HashMap<>();
            wDeleteParwms.put("RuleID", wRuleID);
            this.Delete(wDeleteParwms, " and ID>0 ");

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("MSS_DeleteTransferRange", ex);
        }
    }

    public MSSTransferRange MSS_QueryTransferRange(BMSEmployee wLoginUser, int wCustomerID, String wMaterialGroupFullName,
                                             int wMaterialID, OutResult<Integer> wErrorCode) {
        MSSTransferRange wResult = new MSSTransferRange();
        try {

            List<MSSTransferRange> wList =
                    this.MSS_QueryTransferRangeList(wLoginUser, wCustomerID, null, -1, wMaterialGroupFullName, wMaterialID,
                                                 null, "", Pagination.getMaxSize(), wErrorCode);

            if (wErrorCode.Result != 0 || wList == null || wList.size() <= 0) {
                return wResult;
            }

            for (MSSTransferRange mssTransferRange : wList) {

                if (mssTransferRange.MaterialID == wMaterialID) {
                    return mssTransferRange;
                }
            }

            wList.sort((o1, o2) -> o2.MaterialGroupName.length() - o1.MaterialGroupName.length());

            wResult = wList.get(0);
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("MSS_QueryTransferRange", ex);
        }
        return wResult;
    }

    public MSSTransferRange MSS_QueryTransferRange(BMSEmployee wLoginUser, int wCustomerID,
                                             String wMaterialNo, OutResult<Integer> wErrorCode) {
        MSSTransferRange wResult = new MSSTransferRange();
        try {


            MSSMaterial mssMaterial = CacheUtils.GetCacheInfo(MSSMaterial.class, -1, wMaterialNo);

            if ( mssMaterial == null || mssMaterial.ID <= 0) {
                return wResult;
            }
            wResult = this.MSS_QueryTransferRange(wLoginUser, wCustomerID, mssMaterial.MaterialGroupName, mssMaterial.ID,
                                               wErrorCode);
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("MSS_QueryTransferRange", ex);
        }
        return wResult;
    }


    public List<MSSTransferRange> MSS_QueryTransferRangeList(
            BMSEmployee wLoginUser, int wCustomerID, List<Integer> wCustomerIDList, int wMaterialGroupID,
            String wMaterialGroupFullName,
            int wMaterialID, List<String> wMaterialCode, String wMaterialLike,
            Pagination wPagination, OutResult<Integer> wErrorCode) {
        List<MSSTransferRange> wMSSTransferRangeList = new ArrayList<MSSTransferRange>();
        wErrorCode.set(0);

        try {

            if (wMaterialCode == null)
                wMaterialCode = new ArrayList<>();

            if (wCustomerIDList == null)
                wCustomerIDList = new ArrayList<>();
            wCustomerIDList.removeIf(p -> p <= 0);
            // Step02:查询
            Map<String, Object> wParwms = new HashMap<String, Object>();
            String wSQLText = "";
            wSQLText = StringUtils.Format(
                    "Select t.*,t0.Name as RuleName,t0.Code as RuleCode,t1.Name as CustomerName,t1.Code as CustomerCode,"
                            + " t2.MaterialName  ,t2.Code as MaterialCode,"
                            + " concat(t5.GroupFullName,t5.Name) as MaterialGroupName,t5.Code as MaterialGroupCode,"
                            + " t3.Name as CreatorName ,t4.Name as EditorName  from {0}.mss_transferrange t  "
                            + " left join {0}.mss_transferrule t0 on t0.Active=1 and t.RuleID=t0.ID "
                            + " left join {0}.crm_customer t1 on t1.Active=1 and t.CustomerID=t1.ID "
                            + " left join {0}.mss_material t2 on t2.Active=1 and t.MaterialID=t2.ID "
                            + " left join {0}.mss_materialgroup t5 on t5.Active=1 and t.MaterialGroupID=t5.ID "
                            + " left join {0}.mbs_user t3 on t.CreatorID=t3.ID "
                            + " left join {0}.mbs_user t4 on t.EditorID=t4.ID "
                            + " where  (:CustomerID<0 or  t.CustomerID=:CustomerID ) "
                            + " AND (:CustomerIDList = '''' or  t.CustomerID IN (''{2}'')) "
                            + " AND ((:MaterialID<=0 or  t.MaterialID=:MaterialID ) "
                            + " OR (:MaterialGroupFullName = '''' or  (:MaterialGroupFullName like concat(t5.GroupFullName,t5.Name,''/%'')  and t.MaterialID=0 )))"
                            + " AND (:MaterialGroupID<0 or  t.MaterialGroupID=:MaterialGroupID ) "
                            + " AND (:MaterialLike = '''' or  t2.Code like :MaterialLike or t2.MaterialName like :MaterialLike)"
                            + " AND (:MaterialCode = '''' or  t2.Code in  (''{1}'')) GROUP BY t.ID",
                    super.getDBName(), StringUtils.Join("','", wMaterialCode)
                    , StringUtils.Join("','", wCustomerIDList));

            wSQLText = this.DMLChange(wSQLText);

            wParwms.put("CustomerIDList", StringUtils.Join(",", wCustomerIDList));
            wParwms.put("CustomerID", wCustomerID);
            wParwms.put("MaterialGroupID", wMaterialGroupID);
            wParwms.put("MaterialGroupFullName", wMaterialGroupFullName);
            wParwms.put("MaterialID", wMaterialID);
            wParwms.put("MaterialLike", StringUtils.isEmpty(wMaterialLike) ? "" : ("%" + wMaterialLike + "%"));
            wParwms.put("MaterialCode", StringUtils.Join(",", wMaterialCode));

            wMSSTransferRangeList = super.QueryForList(wSQLText, wParwms, wPagination, MSSTransferRange.class);

            // Step03:配置系统
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("MSS_QueryTransferRangeList", ex);
        }
        return wMSSTransferRangeList;
    }


    public MSSTransferRange MSS_CheckTransferRange(BMSEmployee wLoginUser, MSSTransferRange wMSSTransferRange,
                                             OutResult<Integer> wErrorCode) {
        MSSTransferRange wTransferRange = new MSSTransferRange();
        wErrorCode.set(0);

        try {

            // Step0:查询
            Map<String, Object> wParwms = new HashMap<String, Object>();
            String wSQLText = StringUtils.Format(
                    "Select * from {0}.mss_transferrange "
                            + " where ID!=:ID and CustomerID=:CustomerID and  MaterialGroupID=:MaterialGroupID "
                            + " and  MaterialID=:MaterialID   ",
                    super.getDBName());
            wParwms.clear();
            wParwms.put("ID", wMSSTransferRange.ID);
            wParwms.put("CustomerID", wMSSTransferRange.CustomerID);
            wParwms.put("MaterialGroupID", wMSSTransferRange.MaterialGroupID);
            wParwms.put("MaterialID", wMSSTransferRange.MaterialID);

            wSQLText = this.DMLChange(wSQLText);
            List<Map<String, Object>> wQueryResultList = super.queryForList(wSQLText, wParwms);
            for (Map<String, Object> wSqlDataReader : wQueryResultList) {
                wTransferRange.ID = StringUtils.parseInt(wSqlDataReader.get("ID"));
                wTransferRange.CustomerID = StringUtils.parseInt(wSqlDataReader.get("CustomerID"));
                wTransferRange.MaterialGroupID = StringUtils.parseInt(wSqlDataReader.get("MaterialGroupID"));
                wTransferRange.MaterialID = StringUtils.parseInt(wSqlDataReader.get("MaterialID"));

                wTransferRange.CreatorID = StringUtils.parseInt(wSqlDataReader.get("CreatorID"));
                wTransferRange.CreateTime = StringUtils.parseCalendar(wSqlDataReader.get("CreateTime"));
                wTransferRange.EditorID = StringUtils.parseInt(wSqlDataReader.get("EditorID"));
                wTransferRange.EditTime = StringUtils.parseCalendar(wSqlDataReader.get("EditTime"));
                wTransferRange.Active = StringUtils.parseInt(wSqlDataReader.get("Active"));

            }

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("MSS_CheckTransferRange", ex);
        }
        return wTransferRange;
    }

}
